package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.pojo.JsonResult;
import cn.tedu.charging.common.pojo.param.GunStatusUpdateParam;
import cn.tedu.charging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.common.pojo.vo.UserInfoVO;
import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.order.constant.Constants;
import cn.tedu.charging.order.constant.MqttConstant;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.mqtt.MqttProducer;
import cn.tedu.charging.order.pojo.dto.ChargingDto;
import cn.tedu.charging.order.pojo.dto.StationInfoDto;
import cn.tedu.charging.order.pojo.dto.UserInfoDto;
import cn.tedu.charging.order.pojo.param.OrderAddParam;
import cn.tedu.charging.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private MqttClient mqttClient;
    @Autowired
    private MqttProducer mqttProducer;

    /**
     * 创建订单
     * 1.生成订单号
     * 2.获取场站信息和设备信息
     * 3.获取用户车辆信息
     * 4.给设备发送开始充电指令
     * 5.修改充电桩的状态 为 使用中
     * @param orderAddParam
     * @return
     */
    @Override
    public String createOrder(OrderAddParam orderAddParam) {

        //1.生成订单号
        String orderNo = getOrderNo();
        // 2.获取场站信息和设备信息
        StationInfoDto  stationInfoDto = getStationInfoByGunId(orderAddParam.getGunId());
        //3.获取用户车辆信息
        UserInfoDto  userInfoDto = getUserInfoByUserId(orderAddParam.getUserId());
        //4.给设备发送开始充电指令
        startCharing(orderNo,orderAddParam.getPileId(),orderAddParam.getGunId());
        //5.修改充电桩的状态 为 使用中
        Boolean success = updateGunStatusBusy(orderAddParam.getGunId());


        return "666";
    }

    /**
     * private 最小
     * 默认
     * protected
     * public
     */

    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private UserClient userClient;

    private StationInfoDto getStationInfoByGunId(Integer gunId) {
        JsonResult<StationInfoVO> stationInfo = deviceClient.getStationInfo(gunId);
        if (stationInfo != null) {
            StationInfoVO data = stationInfo.getData();
            if (data != null) {
                StationInfoDto stationInfoDto = new StationInfoDto();
//                stationInfoDto.setStationId(data.getStationId());
                BeanUtils.copyProperties(data,stationInfoDto);
                return stationInfoDto;
            }
        }
        return null;
    }

    private void startCharing(String orderNo, Integer pileId, Integer gunId) {
        //topic 前辍 + 桩id 不加枪的id,设备去订阅这个topic,接收所有发到这个桩上的消息
        String topic = MqttConstant.TOPIC_START_CHARGING_PREFIX + "/" + pileId;
        ChargingDto chargingDto = new ChargingDto();
        chargingDto.setOrderNo(orderNo);
        chargingDto.setPileId(pileId);
        chargingDto.setGunId(gunId);
        chargingDto.setMsg(Constants.START_CHARGING);
        String json = JsonUtils.toJson(chargingDto);
        log.debug("订单服务发送开始充电指令到设备topic:{},消息:{}",topic,json);
        Boolean send = mqttProducer.send(topic,json);
        //如果发送失败,需要重试

    }

    private Boolean updateGunStatusBusy(Integer gunId) {
        GunStatusUpdateParam param = new GunStatusUpdateParam();
        param.setGunId(gunId);
        param.setStatus(Constants.GUN_STATUS_BUSY); //魔数 代码里不要有魔数,应该用常量或枚举
        JsonResult<Boolean> result = deviceClient.updateGunStatus(param);
        if (result != null) {
            return result.getData();
        }

        return false;
    }

    private UserInfoDto getUserInfoByUserId(Integer userId) {
        //TODO
        JsonResult<UserInfoVO> userCarInfo = userClient.getUserCarInfo(userId);
        if (userCarInfo != null) {
            UserInfoVO data = userCarInfo.getData();
            if (data != null) {
                UserInfoDto userInfoDto = new UserInfoDto();
//                BeanUtils.copyProperties(data,userInfoDto);
                userInfoDto.setCarId(data.getCarId());
                return userInfoDto;
            }
        }
        return null;
    }

    private String getOrderNo() {
        return "777";
    }
}
